/*
 * Copyright (c) 2008, Solido Systems
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of Solido Systems nor the names of its contributors may be
 * used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package com.solidosystems.objectkitchen.data;

import java.io.*;
import java.util.*;
import com.solidosystems.objectkitchen.storage.*;

public class Document{
	private String id;
	private int version;
	private List<Long> versionHistory;
	private List<Attachment> attachments;
	private VHash data;
	
	public Document(String id){
		this.id=id;
		version=0;
		data=new VHash();
		versionHistory=new ArrayList<Long>();
		attachments=new ArrayList<Attachment>();
	}
	
	public Document(String id,int version,VHash data){
		this.id=id;
		this.version=version;
		this.data=data;
		versionHistory=new ArrayList<Long>();
		attachments=new ArrayList<Attachment>();
	}
	
	public Document(String id,int version,VHash data,List<Long> history,List<Attachment> attachments){
		this.id=id;
		this.version=version;
		this.data=data;
		versionHistory=history;
		this.attachments=attachments;
	}
	
	public List<String> getAttachments(){
		List<String> results=new ArrayList<String>();
		for(Attachment a:attachments){
			results.add(a.getTitle());
		}
		return results;
	}
	
	public void setAttachment(String title,long offset){
		for(Attachment a:attachments){
			if(a.getTitle().equals(title)){
				a.setOffset(offset);
				return;
			}
		}
		attachments.add(new Attachment(title,offset));
	}
	
	public void removeAttachment(String title){
		for(int i=0;i<attachments.size();i++){
			Attachment a=attachments.get(i);
			if(a.getTitle().equals(title)){
				attachments.remove(i);
				return;
			}
		}
	}
	
	public boolean hasAttachment(String title){
		// Maybe a has should be considered instead?
		for(Attachment a:attachments){
			if(a.getTitle().equals(title))return true;
		}
		return false;
	}
	
	public long getAttachmentOffset(String title){
		// Maybe a has should be considered instead?
		for(Attachment a:attachments){
			if(a.getTitle().equals(title))return a.getOffset();
		}
		return -1;
	}
	
	public String getId(){
		return id;
	}
	
	public void incrementVersion(){
		version++;
	}
	
	public int getVersion(){
		return version;
	}
	
	public VHash getHash(){
		return data;
	}
	
	public List<Long> getHistory(){
		return versionHistory;
	}
	
	public void setHistory(List<Long> history){
		versionHistory=history;
	}
	
	public void writeToStream(DataOutputStream file) throws IOException{
		file.writeUTF(id);
		file.writeInt(version);
		file.writeInt(versionHistory.size());
		for(Long l:versionHistory){
			file.writeLong(l);
		}
		file.writeInt(attachments.size());
		for(Attachment a:attachments){
			file.writeUTF(a.getTitle());
			file.writeLong(a.getOffset());
		}
		// file.writeByte(data.getTypeId());
		data.writeToStream(file);
		file.flush();
	}
	
	public static Document readFromStream(DataInputStream file) throws IOException{
		String id=file.readUTF();
		int version=file.readInt();
		List<Long> history=new ArrayList<Long>();
		int size=file.readInt();
		for(int i=0;i<size;i++){
			history.add(file.readLong());
		}
		List<Attachment> attachments=new ArrayList<Attachment>();
		size=file.readInt();
		for(int i=0;i<size;i++){
			String title=file.readUTF();
			long offset=file.readLong();
			attachments.add(new Attachment(title,offset));
		}
		VHash data=(VHash)Value.readFromStream(file);
		return new Document(id,version,data,history,attachments);
	}
}